package com.kuang.lock;


import java.util.concurrent.TimeUnit;

// 模拟死锁
// 线程1先锁资源A，再锁资源B，线程2先锁资源B，再锁资源A
// 模拟：线程1先获取资源A并锁住、线程2先获取资源B并锁住，
// 这时候，
// 线程1等线程2释放资源B才能继续执行释放资源A,供线程2获取
// 线程2等线程1释放资源A才能继续执行释放资源B,供线程1获取
// 两个线程都在等，但是都获取不到，就发生了死锁
/*
    使用 jps -l定位进程号   查看当前或者的java进程
    使用 jstack 进程号，查看信息，找到死锁
    "T2":
            at com.kuang.lock.MyThread.run(deadLock.java:54)
            - waiting to lock <0x00000000d6c06348> (a java.lang.String)
            - locked <0x00000000d6c06378> (a java.lang.String)
            at java.lang.Thread.run(Thread.java:748)
    "T1":
            at com.kuang.lock.MyThread.run(deadLock.java:54)
            - waiting to lock <0x00000000d6c06378> (a java.lang.String)
            - locked <0x00000000d6c06348> (a java.lang.String)
            at java.lang.Thread.run(Thread.java:748)

 */
public class deadLock {
    public static void main(String[] args) {
        String A = "A";
        String B = "B";

        new Thread(new MyThread(A,B),"T1").start();
        new Thread(new MyThread(B,A),"T2").start();
    }

    /*
        T1lock:A=>to getB   线程都在死等对方释放锁
        T2lock:B=>to getA
     */

}



class MyThread implements Runnable{
    private final String lockA;
    private final String lockB;

    public MyThread(String lockA, String lockB) {
        this.lockA = lockA;
        this.lockB = lockB;
    }

    @Override
    public void run() {
        synchronized (lockA){
            System.out.println(Thread.currentThread().getName()+"lock:"+lockA+"=>to get"+ lockB);
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            synchronized (lockB){
                System.out.println(Thread.currentThread().getName()+"lock:"+lockB+"=> to get"+lockA);
            }
        }
    }

}
